define(["dijit/_WidgetBase",
        "dijit/_TemplatedMixin",
        "dojo/_base/declare",
        "dojo/text!./TableWidget/templates/TableWidget.html",
        "dojo/dom-construct",
        "dojo/_base/lang",
        "dojo/_base/array",
        "dojo/_base/Deferred",
        "dojo/has", 
        "dojo/_base/sniff"],
        function(_WidgetBase,_TemplatedMixin, declare,
        		template, dom, lang, array, Deferred, has) {
	
return declare("TableWidget",[_WidgetBase,_TemplatedMixin], 
	{
		headersInfo: null,
		templateString: template,
		postCreate: function(){
		    this.inherited(arguments);
		},
		fetchData: function(items){
			Deferred.when(items,
		        function(items){
					/* define function to render table body (items in this case), 
					 * bind it to specific arguments (items) and execution context via dojo.hitch()
					 * */
					var bodyFunc = lang.hitch(this,
						function(items,table){
							array.forEach(items, function(item){
								dom.place(this._renderDataRow(item),table);
							}.bind(this));
						},items);
					this._renderTable(bodyFunc);
		        }.bind(this),
		        function(error){
					/* define function to render table body (error row this case), 
					 * bind it to specific arguments (error) and execution context via dojo.hitch()
					 * */
		        	var bodyFunc = lang.hitch(this,
	        			function(error,table){
	        				dom.place(this._renderErrorRow(error),table);
	        			},error);
		        	this._renderTable(bodyFunc);		        	
		        }.bind(this)
		    );
		},
		_renderTable: function(renderBodyFunc) {
			var table = dom.create("table");
			dom.place(this._renderHeaders(this.headersInfo),table);
			renderBodyFunc(table);
			dom.empty(this.domNode);
			dom.place(table,this.domNode);
			// call this to check if used browser is IE, and apply fix behavior sheet if it is
			this._fixIE();
		},
		_renderHeaders: function(headersInfo) {
			var tHead = dom.create("thead");
			var trHeadRow = dom.create("tr", null, tHead);
			array.forEach(headersInfo, function(headerInfo) {
				dom.create("th", { innerHTML: headerInfo.label }, trHeadRow);
			});
			return tHead;
		},
		_renderDataRow: function(dataRow) {
			var trRow = dom.create("tr");
			array.forEach(this.headersInfo, function(headerInfo) {
				var dataToDisplay = '';
				if (typeof headerInfo.transform == 'function') {
					dataToDisplay = headerInfo.transform(headerInfo.key,dataRow);
				} else {
					dataToDisplay = dataRow[headerInfo.key];
				}
				// IE workaround
				if (dataToDisplay === null) {
					dataToDisplay = '';
				}
				dom.create("td", { innerHTML: dataToDisplay }, trRow);
			});
			return trRow;
		},
		_renderErrorRow: function(error) {
			var errRow = dom.create("tr");
			dom.create("td",
				{ innerHTML: "Error occured during fetching data",
				colspan: this.headersInfo.length}, errRow);
			return errRow;
		},
		_fixIE: function() {
			// IE workaround
			if(has("ie")){ 
    	  		/*re-apply behavior sheet, it was already defined in base default.jspx*/
    	  		require(["dojo/behavior"], function(behavior) {
    	  			behavior.apply();
    	  		});
			}
		}
	});	
	
});